package com.note.particleexplosion;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * ================================================
 * 创 建 人：wx
 * 版    本：1.0
 * 创建日期：2021/9/24
 * 描    述：
 * 修 改 人：
 * 修改时间：2021/9/24
 * ================================================
 */
public class ExplosionView extends View {

    private Paint mPaint;

    private Bitmap mBitmap;

    private List<Ball> mBalls;

    private float d = 16;//粒子直径

    private ValueAnimator animator;

    public ExplosionView(Context context) {
        this(context,null);
    }

    public ExplosionView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ExplosionView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mPaint = new Paint();
        mBalls = new ArrayList<>();

    }

    public void setImage(Bitmap bitmap){
        this.mBitmap = bitmap;

        initBalls();
        invalidate();
    }

    private void initBalls() {
        if (mBitmap == null) return;

        for (int i = 0; i < mBitmap.getWidth(); i+= 16) {
            for (int j = 0; j < mBitmap.getHeight(); j+= 16) {
                Ball ball = new Ball();
                ball.color = mBitmap.getPixel(i,j);
                ball.r = d/2;
                ball.x = i + ball.r;
                ball.y = j + ball.r;

                //水平初速度（-20,20）
                ball.vx = (float) ((Math.random() - 0.5) * 40);
                //垂直初速度（-30,30）
                ball.vy = (float) ((Math.random() - 0.5) * 60);
                ball.ax = 0;
                ball.ay = 9.8f;

                mBalls.add(ball);
            }
        }

        animator = ValueAnimator.ofFloat(0,1);
        animator.setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                updateBalls();
                invalidate();
            }
        });

    }

    private void updateBalls() {
        for (Ball ball : mBalls) {
            ball.x += ball.vx;
            ball.y += ball.vy;
            ball.vx += ball.ax;
            ball.vy += ball.ay;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            animator.start();
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mBitmap == null) return;
        if (!animator.isStarted()){
            canvas.drawBitmap(mBitmap,0,0,mPaint);
        }else {
            for (Ball ball : mBalls){
                mPaint.setColor(ball.color);
                canvas.drawCircle(ball.x,ball.y,ball.r,mPaint);
            }
        }
    }
}
